package org.jeecg.modules.quartz.job;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.dingtalk.DingMessageUtils;
import org.jeecg.modules.message.entity.SysMessageTemplate;
import org.jeecg.modules.message.service.ISysMessageTemplateService;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;

import io.finer.erp.jeecg.bas.entity.BasMaterial;
import io.finer.erp.jeecg.bas.entity.BasWarehouse;
import io.finer.erp.jeecg.bas.entity.ZrkDingNotice;
import io.finer.erp.jeecg.bas.entity.ZrkPushSet;
import io.finer.erp.jeecg.bas.entity.ZrkWarninfo;
import io.finer.erp.jeecg.bas.service.IBasMaterialService;
import io.finer.erp.jeecg.bas.service.IBasWarehouseService;
import io.finer.erp.jeecg.bas.service.IZrkDingNoticeService;
import io.finer.erp.jeecg.bas.service.IZrkPushSetService;
import io.finer.erp.jeecg.bas.service.IZrkWarninfoService;
import io.finer.erp.jeecg.stock.entity.StkInventory;
import io.finer.erp.jeecg.stock.service.IStkInventoryService;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class StoreWarningJob implements Job{
	
	@Autowired
	private IBasMaterialService basMaterialService;
	@Autowired
	private IStkInventoryService stkInventoryService;
	@Autowired
	private IZrkWarninfoService zrkWarninfoService;
	@Autowired
	private IBasWarehouseService basWarehouseService;
	@Autowired
	private IZrkDingNoticeService zrkDingNoticeService;
	@Autowired
	private IZrkPushSetService zrkPushSetService;
	@Autowired
	private ISysMessageTemplateService sysMessageTemplateService;
	@Autowired
	private ISysBaseAPI sysBaseApi;
	@Autowired
	private ISysUserService sysUserService;
	
	/**
	 * @description 定时任务执行库存预警检测，获取到预警信息后发送钉钉工作通知
	 * @author heckerstone heckerstone@163.com
	 * @date 2020-08-17
	 */
	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		//查询实时库存
		List<StkInventory> inventoryList=stkInventoryService.list();
		if(null!=inventoryList&&inventoryList.size()>0) {
			for(StkInventory stkInventory:inventoryList) {
				//遍历实时库存判断是否达到预警值
				BasMaterial bm=new BasMaterial();
				int warnAmount=0;
				try {
					bm = basMaterialService.getById(stkInventory.getMaterialId());
					warnAmount = bm.getWarnAmount();
					 //判断该物料是否已经设置停止预警1:停止预警；0:未停止
					if(bm.getIsStop()==0) {
						//判断是否达到预警值
						if(stkInventory.getQty().compareTo(new BigDecimal(warnAmount))<0) {
							//实时库存数量小于预警值则记录该条记录并开始预警（钉钉通知或者其他通知方式）
							ZrkWarninfo zrkWarninfo=new ZrkWarninfo();
							zrkWarninfo.setMaterialAmount(stkInventory.getQty().toString());
							zrkWarninfo.setMaterialName(bm.getName());
							//查询仓库名称
							BasWarehouse basWarehouse=basWarehouseService.getById(stkInventory.getWarehouseId());
							//数量预警信息
							char c='d';
							int da=0;
							try {
								da=DateUtils.dateDiff(c, DateUtils.parseCalendar(DateUtils.formatDateTime(), "yyyy-MM-dd HH:mm:ss"), DateUtils.parseCalendar(DateUtils.formatDate(stkInventory.getCreateTime(),"yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss"));
							} catch (ParseException e) {
								e.printStackTrace();
							}
							String content="存储在："+basWarehouse.getName()+"的物料名称："+bm.getName()+"的实时库存为："+stkInventory.getQty()+",小于该物料的预警值："+warnAmount+",请及时补充库存！该物料已使用"+da+"天，请参考使用时长设置库存数量合理值。";
							zrkWarninfo.setMaterialContent(content);
							zrkWarninfo.setMaterialId(stkInventory.getMaterialId());
							zrkWarninfo.setType("1");
							zrkWarninfo.setMaterialTime(da);//设置积压时间
							zrkWarninfoService.save(zrkWarninfo);//保存到数据
							//检测到之后发送钉钉工作通知，注意设置定时任务执行周期，开发时设置为1分中执行一次，生产环境下请根据具体情况设置执行周期，建议一天执行一次即可，即每天上午9点发送一次通知
//							List<ZrkDingNotice> noticeList=zrkDingNoticeService.list();
//							String userids="";
//							if(null!=noticeList&&noticeList.size()>0) {
//								for(ZrkDingNotice dingNotice:noticeList) {
//									if(userids.equals("")) {
//										userids=dingNotice.getDingUserid();
//									}else {
//										userids+=","+dingNotice.getDingUserid();
//									}
//								}
//							}
//							//调用钉钉工作通知接口发送钉钉工作通知给已设置的人，数量预警信息
//							DingMessageUtils.sendDingMessage(userids, content);
							//查询短信模版及提醒人信息
							Collection<ZrkPushSet> col=zrkPushSetService.list();
							if(null!=col&&col.size()>0) {
								Iterator<ZrkPushSet> ite=col.iterator();
								while(ite.hasNext()) {
									ZrkPushSet zps=ite.next();
									//库存预警消息类型
									if(zps.getMessageTpe().equals("3")) {
										//生产工单信息需要发送钉钉消息提醒任务分配，查询短信模版
										SysMessageTemplate sysMessage=sysMessageTemplateService.getById(zps.getMessageId());
										//替换模版变量
										String messageContent=sysMessage.getTemplateContent();
										//发送消息时内容带着<p></p>,此处需要替换掉
										messageContent=content;
										//查询提醒人钉钉ID
										SysUser sysUser=sysUserService.getById(zps.getUserId());
										boolean flag=DingMessageUtils.sendDingMessage(sysUser.getThirdId(), messageContent);
										if(flag) {
											//发送消息成功后,将该任务单状态设置为已推送,防止多次推送（统一消息发送多次在钉钉接口处理的时候会提示143106，该错误码代表发送消息重复，143105:表示企业自建应用每日推送给用户的消息超过上限）
											//发送系统消息
											sysBaseApi.sendSysAnnouncement("admin", sysUser.getUsername(),sysMessage.getTemplateName(), messageContent);
										}
									}
								}
							}
						}else {
							//判断时间阈值
							String timeContent="";
							//时间预警信息
							char d='d';
							try {
								//查询仓库名称
								BasWarehouse basWarehouse=basWarehouseService.getById(stkInventory.getWarehouseId());
								int day=DateUtils.dateDiff(d,DateUtils.parseCalendar(DateUtils.formatDateTime(), "yyyy-MM-dd HH:mm:ss"),DateUtils.parseCalendar(DateUtils.formatDate(stkInventory.getCreateTime(),"yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss"));
		                        if(new BigDecimal(bm.getWarnTime()).compareTo(new BigDecimal(day))<0) {
		                        	//时间超期，积压提醒
		                        	timeContent="存储在："+basWarehouse.getName()+"的物料名称："+bm.getName()+"的实时库存为："+stkInventory.getQty()+"超过"+bm.getWarnTime()+"天未使用,请尽快使用！（建议将物料时间阈值增加"+new BigDecimal(day).subtract(new BigDecimal(bm.getWarnTime()))+"天,或者减少库存量，防止库存积压。)";
		                        	ZrkWarninfo zrkWarninfo2=new ZrkWarninfo();
		        					zrkWarninfo2.setMaterialAmount(stkInventory.getQty().toString());
		        					zrkWarninfo2.setMaterialName(bm.getName());
		        					zrkWarninfo2.setMaterialContent(timeContent);
		        					zrkWarninfo2.setMaterialId(stkInventory.getMaterialId());
		        					zrkWarninfo2.setType("2");//时间类型
		        					zrkWarninfo2.setMaterialTime(day);//设置积压时间
		        					zrkWarninfoService.save(zrkWarninfo2);//保存到数据
		        					Collection<ZrkPushSet> col=zrkPushSetService.list();
		    						if(null!=col&&col.size()>0) {
		    							Iterator<ZrkPushSet> ite=col.iterator();
		    							while(ite.hasNext()) {
		    								ZrkPushSet zps=ite.next();
		    								//库存预警消息类型
		    								if(zps.getMessageTpe().equals("3")) {
		    									//生产工单信息需要发送钉钉消息提醒任务分配，查询短信模版
		    									SysMessageTemplate sysMessage=sysMessageTemplateService.getById(zps.getMessageId());
		    									//替换模版变量
		    									String messageContent=sysMessage.getTemplateContent();
		    									//发送消息时内容带着<p></p>,此处需要替换掉
		    									messageContent=timeContent;
		    									//查询提醒人钉钉ID
		    									SysUser sysUser=sysUserService.getById(zps.getUserId());
		    									boolean flag=DingMessageUtils.sendDingMessage(sysUser.getThirdId(), messageContent);
		    									if(flag) {
		    										//发送消息成功后,将该任务单状态设置为已推送,防止多次推送（统一消息发送多次在钉钉接口处理的时候会提示143106，该错误码代表发送消息重复，143105:表示企业自建应用每日推送给用户的消息超过上限）
		    										//发送系统消息
		    										sysBaseApi.sendSysAnnouncement("admin", sysUser.getUsername(),sysMessage.getTemplateName(), messageContent);
		    									}
		    								}
		    							}
		    						}
		                        }
							} catch (ParseException e) {
//								e.printStackTrace();
							}
						}
					}
				} catch (Exception e1) {
					//防止出现实时库存与物料不对应的情况
					
				}
			}
		}
	}

}
